<?php
//PingBuWang.Com
//Copyright (c) 2017~2099 http://www.pingbuwang.com All rights reserved.
namespace app\article\model;

use think\Cache;
use mip\Paginationm;
use think\Db;
use think\Log;
use think\Model;
use think\Controller;

class Article extends Model
{
    protected function initialize(){
        //继承父类中的initialize()
        parent::initialize();
    }

    public function getOne($where,$order = 'sort desc',$q = null){
        $cacheKey = md5('c_article_getOne_'.serialize($where).'_'.$q);
        $gg = Cache::get($cacheKey);
        if($gg){
            return $gg;
        }

        $art=db('articles')->where( $where ) ->order($order) ->limit(1) ->find();

        $art= $this->_updateArticleInfo($art,$q);

        Cache::set($cacheKey,$art,60*60);
        Cache::tag('article',$cacheKey);
        return $art;
    }

    public function getById($id,$q=null){
        $cacheKey = md5('c_article_getById_'.$id.'_'.$q);
        $gg = Cache::get($cacheKey);
        if($gg){
            return $gg;
        }

        $art=db('articles')->where(array('id'=>$id) ) ->find();
        $art= $this->_updateArticleInfo($art,$q);

        Cache::set($cacheKey,$art,60*60);
        Cache::tag('article',$cacheKey);
        return $art;

    }

    public function getList($where=null,$order='sort desc',$page=1,$limit=null,$q=null){

        $cacheKey = md5('c_article_getList_'.serialize($where).'_'.$order.'_'.$page.'_'.$limit.'_'.$q);

        $gg = Cache::get($cacheKey);
        if($gg){
            return $gg;
        }

        $ord1 = $order;
        if(!$ord1 || $ord1==''){
            $ord1='sort desc';
        }

        if(!$page || $page==''){
            $page = 1;
        }
        if(!$limit || $limit==''){
            $limit = 100;
        }

        $dblst = db('articles');
        if(!empty($where)){
            $dblst = $dblst->where($where);
        }
        if(!empty($q)){
            $where2 = array('id'=>array('in',function($query)use($q){$query->db('articlesContent')->where(array('content'=>array('like','%'.$q.'%'))) ; } ));
            $dblst = $dblst->where($where2);
        }

        $dblist = $dblst->page($page,$limit)->order($ord1)->select() ;

        if($dblist) {
            foreach ($dblist as $k => $v) {
                $user = db('Users')->where('uid', $v['uid'])->find();
                $cate =  model('app\article\model\ArticleCategory')->getById($v['cid']);

                $dblist[$k]['categoryInfo'] = $cate;
                $dblist[$k]['userInfo'] = $user;
                $dblist[$k]['url'] = $this->_getUrlByArticle($dblist[$k],$q);

                $dblist[$k]['ts_publish_time'] = strtotime($v['publish_time']);
                $dblist[$k]['ts_create_time'] = strtotime($v['create_time']);
                $dblist[$k]['ts_edit_time'] = strtotime($v['edit_time']);

                if($v['status']==1){
                    $dblist[$k]['str_status']='发布中';
                }else if($v['status']==2){
                    $dblist[$k]['str_status']='暂存';
                }else if($v['status']==0){
                    $dblist[$k]['str_status']='禁用';
                }else{
                    $dblist[$k]['str_status']='其他';
                }

            }
        }

        Cache::set($cacheKey,$dblist,60*60);
        Cache::tag('article',$cacheKey);

        return $dblist;
    }

    public function getCount($where=null,$q=null){
        $cacheKey =  md5('c_article_getCount_'.serialize($where).'_'.$q);
        $gg = Cache::get($cacheKey);
        if($gg){
            return $gg;
        }

        $dblst = db('articles');
        if(!empty($where)){
            $dblst = $dblst->where($where);
        }
        if(!empty($q)){
            $where2 = array('id'=>array('in',function($query)use($q){$query->table('articlesContent')->where(array('content'=>array('like','%'.$q.'%'))) ; } ));
            $dblst = $dblst->where($where2);
        }

        $cnt = $dblst->count() ;

        Cache::set($cacheKey,$cnt,60*60);
        Cache::tag('article',$cacheKey);

        return $cnt;
    }

    public function getPage($where=null,$order='sort desc',$page=1,$limit=15,$q=null ){
        $ord1 = $order;
        if(!$ord1 || $ord1==''){
            $ord1='sort desc';
        }

        if(!$page || $page==''){
            $page = 1;
        }
        if(!$limit || $limit==''){
            $limit = 15;
        }

        $lst = $this->getList($where,$ord1,$page,$limit,$q);
        $cnt =$this->getCount($where,$q);

        $pageCount = ceil(($cnt+$limit-1)/$limit ) ;

        $arr = array('list'=>$lst,'currentPage'=> $page,'limit'=>$limit , 'pageCount'=>$pageCount , 'total'=>$cnt );
        return $arr;
    }


    /**
     * 刷新浏览次数，同一个用户1个小时内算做一次缓存
     * @param $id
     * @param $uid
     * @return bool
     * @throws \think\Exception
     */
    public function updateViews($id,$where = null){
        $ua =$_SERVER['HTTP_USER_AGENT'];

        // 判断是否百度爬虫
        $spiderField = null;
        if(strpos($ua,'Baiduspider')!==false){
            $spiderField = 'baidu_spider_num';
        }
        if(strpos($ua,'Google')!==false || strpos($ua,'gsa-crawler')!==false ){
            $spiderField = 'google_spider_num';
        }

        if($spiderField){

            $db1 = db('articles')->where(array('id'=> $id) ) ;
            if(!empty($db1)){
                $db1 = $db1->where($where);
                $db1->setInc($spiderField);
                return true;
            }
            return false;
        }

        $cacheKey = md5( 'c_article_updateViews_' . session_id() .'_'. $id ) ;
        $tempCache = Cache::get($cacheKey);
        if ($tempCache) {
            return false;
        }
        Cache::set($cacheKey, 1 ,60*60);
        $db1 = db('articles')->where( array('id'=> $id) ) ->where($where)->setInc('views');
        return true;
    }

    // 获取下一条记录
    public function getNext($articleId){
        // 参数cid的值为空
        $art1 = db('articles')->where(' id ='.$articleId)->field('cid,fullcid,sort')->find();
        if(!$art1){
            return false;
        }

        $art2 = db('articles')->where(array("cid"=>$art1['cid'],'status'=>1, 'sort'=>array('lt',$art1['sort'] )) )->field('id')->order('sort desc')->limit(1)->find();
        if($art2==null){
            return false;
        }

        $art3 = $this->getById($art2['id']);
        return $art3;
    }

    /**
     * 获取前一个文章
     * @param $articleId
     * @return array|bool|false|\PDOStatement|string|Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getPrev($articleId){
        // 参数cid的值为空
        $art1 = db('articles')->where('id ='.$articleId)->field('cid,fullcid,sort')->find();
        if(!$art1){
            return false;
        }

        $art2 = db('articles')->where(array("cid" => $art1['cid'], 'status'=>1,'sort'=>array('gt' ,$art1['sort']) ) )->field('id')->order('sort asc')->limit(1)->find();
        if(!$art2){
            return false;
        }

        $art3 = $this->getById($art2['id']);
        return $art3;
    }

    public function doAddGetId($arr){
        $id = db('articles')->insertGetId($arr);
        if($id){
            Cache::clear('article');
        }
        return $id;
    }

    public function doEdit($id,$arr){
        $res =db('articles')->where('id',$id)->update($arr);
        if($res){
            Cache::clear('article');
        }
        return $res;
    }

    public function doDelByIds($ids){
        $res = 0;

        $res += db('articlesContent')->where(array('id'=>array('in',$ids) ) )->delete();
        $res += db('articles')->where(array('id'=>array('in',$ids) ))->delete();
        $res += db("tagsArticle")->where(array('article_id'=>array('in',$ids) ))->delete();

        if($res){
            Cache::clear('article');
        }
        return $res;
    }

    public function doAddContent($id,$content){
        $res = db('articlesContent')->insert(array('article_id' => $id,
            'content' => htmlspecialchars($content),
        ));

        if($res){
            Cache::clear('article');
        }
        return $res;

    }
    public function doEditContent($id,$content){
        $res = db('articlesContent')->where('article_id',$id)
            ->update(array('content' => htmlspecialchars($content) ));

        if($res){
            Cache::clear('article');
        }
        return $res;

    }

    /********************   私有方法   ***************************/

    /**
     * 根据内容id获取article的内容
     * @param $content_id
     * @return bool|string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    private function getContentById($content_id)
    {
        if (!$content_id) {
            return false;
        }
        return htmlspecialchars_decode(db('articlesContent') ->where('article_id', $content_id)->find()['content']);
    }

    /**
     * 获取文章的访问地址
     * @param $item
     * @param null $domain
     * @return bool|string
     */
    private function _getUrlByArticle($item,$q=null)
    {
        $tempId = $item['id'];
        $catePreurl = $item['categoryInfo']['detail_preurl'];

        if(!$catePreurl){
            $tmplInfo = model('app\setting\model\Template')->getInfoByFileName(config('mipInfo')['template']);
            if(tmplInfo) {

                $catePreurl = $tmplInfo['detail_preurls'][0];
            }
        }
        if($catePreurl){
            if($q){
                return $catePreurl . $tempId . '/'.$q.'/';
            }else{
                return $catePreurl . $tempId . '.html';
            }

        }
        return false;
    }

    /**
     * 根据articleId和正文内容，获取文章的简介
     * @param $id
     * @param $content
     */
    public function getDescriptionByContent($content){
        if(!$content){
            return false;
        }

        $str = htmlspecialchars_decode($content);
        $str = decodeHtmlForRichEditor($str);

        if(mb_strlen($str)>150){
            $str = mb_substr($str,0,150);
        }

        return $str;
    }

    /**
     * 处理文章正文关联的 tag 关键字
     * 1 获得所有的 tag 关键字
     * 2
     * @param $article
     */
    public function updateTagsByArticle($articleId,$articleContent){

        $content = htmlspecialchars_decode( $articleContent );
        $content = decodeHtmlForRichEditor( $content );

        $arrTags = db('tags')->select();

        $ires = 0;

        db('tagsArticle')->where(array('article_id'=>$articleId ))->delete();

        foreach($arrTags as $k => $v){

            if(strpos($articleContent,$v['title']) === false){
                continue;
            }else{
                // 删除掉已 经存在的该文章的匹配数据
                $ires += db('tagsArticle')->where('tags_id = "'.$v['id'].'" and article_id = '.$articleId )->delete();
            }

            $chapters = getChapterByKeyword($content,$v['title']);

            foreach($chapters as $k2=>$v2){
                if(strlen($v2)>300){
                    $v2 = mb_substr($v2,0,300);
                }
                $ires += db('tagsArticle')->insert(array('id'=>uuid(),'tags_id'=>$v['id'],'article_id'=>$articleId,'article_chapter'=>$v2) );
                break;
            }

        }

        if($ires){
            Cache::clear('article');
        }

    }

    /**
     * 获取查询结果下的阅读信息
     * 1 文章数
     * 2 总字数
     * 3 总图片数
     * 4 估算阅读秒数
     * 5 估算阅读分钟数
     * @param $where
     */
    public function getArticlesInfo($where){
        // 1 获取where条件下的所有文章的Id数组
        $artIds = db('articles')->where($where)->field('id')->select();

        // 2 获取每篇文章的 content 数组
        $arrIds = array_values( array_column($artIds,'id') ) ;
        Log::error('ids ==='.json_encode($arrIds,JSON_PRETTY_PRINT) );
        $artContents = db('articlesContent')->where( array('article_id' =>array('in', $arrIds) ) ) ->select();

        // 3 循环计算 字数、图片数
        $totalWordCount = 0;
        $totalImgCount = 0;

        foreach ($artContents as $k1=>$v1){
            $decodeContent = decodeHtmlForRichEditor( htmlspecialchars_decode($v1['content']) );
            $wordCount = mb_strlen($decodeContent);
            $totalWordCount+=$wordCount;

            $imgCount = count( getImgsFromContent($v1['content']) ) ;
            $totalImgCount += $imgCount;
        }

        // 4 计算阅读秒数
        $readSeconds= getReadSeconds($totalWordCount,$totalImgCount);

        // 5 计算阅读分钟数
        $readMinutes = ceil($readSeconds/60);

        $res = array('articleCount'=>count($artContents),'totalWordCount'=>$totalWordCount,'totalImgCount'=>$totalImgCount,'readSeconds'=>$readSeconds,'readMinutes'=>$readMinutes );

        return $res;
    }

	private function _getTagsByArticleId($articleId){
		// 获取 文章管理的标签
		$tagsIds = db('tagsArticle')->distinct(true)->where( array('article_id' => $articleId) )->field('tags_id')->select();

		$arrIds = [];
		foreach($tagsIds as $k=>$v){
			$arrIds[] = $v['tags_id'];
		}
		$arrTags = db('tags')->where(array('id'=>array('in',$arrIds))) ->select();
		return $arrTags;
	}



    /**
     * 推送一条信息到 百度，熊掌号，MIP等
     * @param $createInfo
     * @return bool|string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function itemPushUrl($createInfo)
    {
        $domainSitesList = db('domainSites')->select();

        // 如果是超级站点
        if ($this->mipInfo['superSites'] && $domainSitesList) {
            foreach ($domainSitesList as $key => $val) {
                $domainSettingsInfo = db('domainSettings')->where('id', $val['id'])->find();
                $urls = $this->getUrlByArticle($createInfo, $val['http_type'] . $val['domain']);
                $urls = explode(',', $urls);
                if ($domainSettingsInfo['mipAutoStatus'] && $domainSettingsInfo['mipApi']) {
                    $result = pushData($domainSettingsInfo['mipApi'], $urls);
                }

                if ($domainSettingsInfo['ampAutoStatus'] && $domainSettingsInfo['ampApi']) {
                    $result = pushData($domainSettingsInfo['ampApi'], $urls);
                }

                if ($domainSettingsInfo['xiongZhangStatus'] && $domainSettingsInfo['xiongZhangNewAutoStatus'] && $domainSettingsInfo['xiongZhangNewApi']) {
                    $result = pushData($domainSettingsInfo['xiongZhangNewApi'], $urls);
                }

                if ($domainSettingsInfo['yuanChuangAutoStatus'] && $domainSettingsInfo['yuanChuangApi']) {
                    $result = pushData($domainSettingsInfo['yuanChuangApi'], $urls);
                }

                if ($domainSettingsInfo['linkAutoStatus'] && $domainSettingsInfo['linkApi']) {
                    $result = pushData($domainSettingsInfo['linkApi'], $urls);
                }
            }
        } else {

            // 判断是自动提交到百度，则直接自动提交到百度，包括百度原创、官方号、MIP站点
            $urls = $this->getUrlByArticle($createInfo);
            $urls = explode(',', $urls);

            if (is_array($urls)) {
                if ($this->mipInfo['baiduYuanChuangStatus']) {
                    $api = $this->mipInfo['baiduYuanChuangUrl'];
                    $result = pushData($api, $urls);
                }
                if ($this->mipInfo['baiduTimePcStatus']) {
                    $api = $this->mipInfo['baiduTimePcUrl'];
                    $result = pushData($api, $urls);
                }
                if ($this->mipInfo['guanfanghaoStatus']) {
                    if ($this->mipInfo['guanfanghaoStatusPost']) {
                        $api = $this->mipInfo['guanfanghaoRealtimeUrl'];
                        $result = pushData($api, $urls);
                    }
                }
                if ($this->mipInfo['mipPostStatus']) {
                    $api = $this->mipInfo['mipApiAddress'];
                    $result = pushData($api, $urls);
                }
            }
        }
        return $result;

    }

    /**
     * 重新排序，把某一条文章在他的类别中向前移动
     * @param $artId
     * @return int|\think\response\Json
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function moveSort($artId,$direct){
        // 先获得分类Id
        $arrcid = db('articles')->where('id',$artId)->field('cid')->find();
        if( !$arrcid ){
            return 3;
        }

        // 获得分类下所有的新闻列表
        $arts = db('articles')->where(array('cid' =>$arrcid['cid'] ) )->field('id')->order('sort asc,publish_time desc ')->select();
        if(!$arts){
            return 5;
        }

        $pos = array_search(array('id'=>$artId),$arts);

        // 如果是向上移动
        if($direct=='down' && $pos>0){
            $prev = $arts[$pos-1];
            $curr = $arts[$pos];

            $arts[$pos] = $prev;
            $arts[$pos-1] = $curr;
        }else if($direct=='up'&& $pos<count($arts)-1 ){
            $next = $arts[$pos+1];
            $curr = $arts[$pos];

            $arts[$pos] = $next;
            $arts[$pos+1] = $curr;
        }else{
            return  0;
        }

        foreach($arts as $k1=>$v1){
            db('articles')->where('id',$v1['id'])->update(['sort'=>$k1+1]);
        }
        Cache::clear('article');
        return 1;

    }

    private function _updateArticleInfo($art,$q=null){
        if ($art) {
            $user = db('Users')->where('uid', $art['uid'])->find();

            $art['userInfo'] = $user;
            $art['content'] = $this->getContentById($art['id']);
            $art['mipContent'] = convertContentForMip($art['content']);

            // 计算正文字数
            $decodeContent = decodeHtmlForRichEditor($art['content']);
            $art['wordCount'] = mb_strlen($decodeContent);


            // 判断content中是否包括 <pre><code class="lang-html">
            if(mb_strpos($art['mipContent'],'<pre><code class=') > 0){
                $art['has_code'] = true;
            }else{
                $art['has_code'] = false;
            }

            // 如果$q 不为null 则加上关键搜索状态
            if($q!=null){
                $art['mipContent'] = str_replace($q,"<span class='search_q'>".$q."</span>",$art['mipContent']);
            }

            $imgs = getImgsFromContent($art['content'] );
            $art['imgCount'] = count($imgs);
            if($imgs&&count($imgs)==2){
                $art['srcimgs'] = $imgs[0];
                $art['fullimgs'] = $imgs[1];
            }

            $art['categoryInfo'] = model('app\article\model\ArticleCategory')->getById($art['cid']);
            $art['url'] = $this->_getUrlByArticle($art);

            // 加载 JSON-LD 的图片，取3张图片
            $mipimgs =[];
            for ($i = 0; $art['fullimgs'] != null && $i < 3 && $i < count($art['fullimgs']); $i++) {
                $mipimgs[$i] = $art['fullimgs'][$i];
            }

            $art['ogImages'] = preg_replace('/\\\\\//','/',json_encode($mipimgs));

            $art['ts_publish_time'] = strtotime($art['publish_time']);
            $art['ts_create_time'] = strtotime($art['create_time']);
            $art['ts_edit_time'] = strtotime($art['edit_time']);

            // 计算阅读时长
            $readSeconds = getReadSeconds($art['wordCount'],$art['imgCount']);
            $readMinutes = ceil($readSeconds/60);
            $art['readMinutes'] = $readMinutes;

            // 获取文章的标签列表
            $art['tags'] = $this->_getTagsByArticleId($art['id']);

            return $art;
        } else {
            return null;
        }
    }

}